package phoenix.web.page_objects.features;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.TestException;
import phoenix.core.PhoenixManager;
import phoenix.core.base.extensions.PageBaseWebExt;
import phoenix.core.config.extensions.ConfigExt;
import phoenix.web.locators.base.features.MessengerLocatorsBase;

public class MessengerPage extends PageBaseWebExt
{
	/**
	 * Initializes PageBaseWebExt
	 * @param p_manager PhoenixManager instance
	 */
	public MessengerPage(PhoenixManager p_manager)
	{
		super(p_manager);
	}

	public MessengerLocatorsBase elements()
	{
		switch (manager.testModel().getSiteName())
		{
			case ConfigExt.SITE_ID_CLICKANDFLIRT:
			{
				return new phoenix.web.locators.clickandflirt.features.MessengerLocators();
			}
			case ConfigExt.SITE_ID_LOCALSGOWILD:
			{
				return new phoenix.web.locators.localsgowild.features.MessengerLocators();
			}
			case ConfigExt.SITE_ID_EBONYFLIRT:
			{
				return new phoenix.web.locators.ebonyflirt.features.MessengerLocators();
			}
			case ConfigExt.SITE_ID_CHEECKYLOVERS:
			{
				return new phoenix.web.locators.cheekylovers.features.MessengerLocators();
			}
			case ConfigExt.SITE_ID_WILDBUDDIES:
			{
				return new phoenix.web.locators.wildbuddies.features.MessengerLocators();
			}
			case ConfigExt.SITE_ID_FLIRT:
			{
				return new phoenix.web.locators.flirt.features.MessengerLocators();
			}
			case ConfigExt.SITE_ID_FOREIGNGIRLFRIEND:
			{
				return new phoenix.web.locators.foreigngirlfriend.features.MessengerLocators();
			}
			case ConfigExt.SITE_ID_BENAUGHTY:
			{
				return new phoenix.web.locators.benaughty.features.MessengerLocators();
			}
			case ConfigExt.SITE_ID_NAUGHTYFEVER:
			{
				return new phoenix.web.locators.naughtyfever.features.MessengerLocators();
			}
			case ConfigExt.SITE_ID_MATUREDATING:
			{
				return new phoenix.web.locators.maturedating.features.MessengerLocators();
			}
			default:
			{
				return null;
			}
		}
	}

	public boolean isPopInPresent()
	{
		return wd().isElementDisplayed(elements().btnPopIn);
	}

	public boolean isMinimizedPresent()
	{
		try
		{
			wd().waitForPresence(elements().btnClose, " [mini] Close button Minimized", true, 2);
			wd().waitForPresence(elements().elTitleIcon, " [mini] Icon Messenger Minimized", true, 2);
			wd().waitForPresence(elements().btnMaximize, " [mini] Maximize button Minimized", true, 2);
			wd().waitForPresence(elements().txtTitle, " [mini] Messenger icon Minimized", true, 2);
		}
		catch (Exception p_ex)
		{
			log().warn("isMinimizedPresent " + p_ex.toString());
			return false;
		}
		return true;
	}

	public boolean isSmallPresent()
	{
		try
		{
			if (manager.isBN())
			{
				wd().waitForVisibility(elements().btnVideo, " [small] Video button", true, 2);
			}

			wd().waitForPresence(elements().btnClose, " [small] Close button", true, 2);
			wd().waitForPresence(elements().btnMinimize, " [small] Minimize button", true, 2);
			wd().waitForPresence(elements().btnPopOut, " [small] Pop-out button", true, 2);
			wd().waitForPresence(elements().bntFAQ, " [small] Question mark button", true, 2);
			wd().waitForPresence(elements().btnOptions, " [small] Options button", true, 2);
			wd().waitForPresence(elements().elHistory, " [small] Messenger history block", true, 2);
			wd().waitForPresence(elements().blockMessageInputField, " [small] Message input field", true, 2);

		}
		catch (Exception p_ex)
		{
			log().warn("isSmallPresent " + p_ex.toString());
			return false;
		}
		return true;
	}

	public boolean isLargePresent()
	{
		try
		{
			if (manager.isBN())
			{
				wd().waitForVisibility(elements().btnVideo, "[big] Video button", true, 2);
			}

			wd().waitForVisibility(elements().btnClose, "[big] Close button", true, 2);
			wd().waitForVisibility(elements().btnMinimize, "[big] Minimize button", true, 2);
			wd().waitForVisibility(elements().btnPopIn, "[big] Change mode button", true, 2);
			wd().waitForVisibility(elements().bntFAQ, "[big] FAQ button", true, 2);
			wd().waitForVisibility(elements().btnOptions, "[big] Options button", true, 2);
			wd().waitForVisibility(elements().elHistory, "[big] Messenger history block", true, 2);
			wd().waitForVisibility(elements().blockMessageInputField, "[big] Message input field", true, 2);

			if (!manager.isNF())
			{
				wd().waitForVisibility(elements().btnDelete, "[big] Remove button", true, 2);
			}

			wd().waitForVisibility(elements().btnSmiles, "[big] Smiles button", true, 2);
			wd().waitForVisibility(elements().txtTitle, "[big] Block User Name", true, 2);
			;
			wd().waitForVisibility(elements().btnSubmit, "[big] Submit button", true, 2);
		}
		catch (Exception p_ex)
		{
			log().warn("isLargePresent " + p_ex.toString());
			return false;
		}
		return true;
	}

	public void clickPopIn()
	{
		wd().waitForVisibility(elements().btnPopIn, "Change mode button");
		wd().click(elements().btnPopIn);
		wd().wait(2);
	}

	public void clickPopOut()
	{
		wd().waitForVisibility(elements().btnPopOut, "Enlarge size of window");
		wd().click(elements().btnPopOut);
		wd().wait(2);
	}

	public void clickMinimize()
	{
		wd().waitForVisibility(elements().btnMinimize, "Minimize button");
		wd().click(elements().btnMinimize);
		wd().wait(2);
	}

	public void clickMaximize()
	{
		wd().waitForVisibility(elements().btnMaximize, "Maximize button");
		wd().click(elements().btnMaximize);
		wd().wait(2);
	}

	public void clickClose()
	{
		wd().wait(2);
		wd().waitForPresence(elements().btnClose, "Close button");
		wd().click(elements().btnClose);
		wd().wait(2);
	}

	public Integer getCounter()
	{
		String txt = "";

		if (wd().isElementDisplayed(elements().elCounter))
		{
			txt = wd().getText(elements().elCounter);
		}

		if (!txt.isEmpty())
		{
			try
			{
				return Integer.parseInt(txt);
			}
			catch (Exception p_ex)
			{
				log().info("Unable to parse string " + txt);
			}
		}
		return 0;
	}

	public String getTitle()
	{
		try
		{
			wd().waitForPresence(elements().txtTitle, "Messenger title");
			String text = wd().getText(elements().txtTitle);

			if (manager.isNF())
			{
				int pos = text.indexOf(" ");
				text = (pos == -1) ? text : text.substring(0, pos);
			}

			return text;
		}
		catch (Exception p_ex)
		{
			log().warn("getTitle value isn't found" + p_ex.toString());
			return "";
		}
	}

	public void clickById(String p_uid)
	{
		wd().click(elements().btnUser(p_uid));
	}

	public void clickMessenger()
	{
		wd().waitForPresence(elements().btnMessageOpen, "Messenger Button");
		wd().waitForVisibility(elements().btnMessageOpen, "Messenger Button");
		wd().wait(3); // Js lazy load
		wd().click(elements().btnMessageOpen);
		wd().wait(3); // Js lazy load
	}

	public void closeMessenger()
	{
		wd().waitForPresence(elements().btnClose, "Close Messenger Button");
		wd().waitForVisibility(elements().btnClose, "Close Messenger Button");
		wd().click(elements().btnClose);
	}

	/**
	 * @param isRead true for seen message, false for unseen
	 */
	public void checkStatusOfDelivery(Boolean isRead)
	{
		if (isRead)
		{
			wd().waitForPresence(elements().blockRead, "Block read");
		}
		else
		{
			wd().waitForPresence(elements().blockUnread, "Block unread");
		}
	}

	public Map<Integer, String[]> getListOfUsers()
	{
		Map<Integer, String[]> p_userList = new HashMap<>();

		wd().waitForVisibility(elements().blockUserListMessenger, "User list in messenger");
		WebElement userlist = wd().getWebElement(elements().blockUserListMessenger);
		List<WebElement> userprofiles = userlist.findElements(elements().blockItemUser);

		if (userprofiles.size() == 0)
		{
			throw new TestException("No users have been found in messenger list");
		}

		log().info("Found " + userprofiles.size() + " profiles in messenger");

		Integer position_in_list = 1;
		for (WebElement elementProfile : userprofiles)
		{
			String user_id; // UserId
			String numberOfAlerts; // Number of unseen messages
			String statusUser; // online / offline
			String user_name; // User screen name

			// Getting user_id key
			try
			{
				user_id = elementProfile.findElement(elements().blockUserID).getAttribute("data-userid");
			}
			catch (Exception p_ex)
			{
				throw new TestException("Unable to read userID " + p_ex.toString());
			}

			// Getting number of incoming messages from user
			try
			{
				if (wd().isElementPresent(elements().blockCounter))
				{
					numberOfAlerts = elementProfile.findElement(elements().blockCounter).getText();
				}
				else
				{
					log().warn("Can't find counter of incoming message");
					numberOfAlerts = "0";
				}
			}
			catch (Exception p_ex)
			{
				throw new TestException("Unable to read counter value " + p_ex.toString());
			}

			// Getting user status online / recently online
			try
			{
				statusUser = elementProfile.findElement(elements().blockOnline).getText();
				statusUser = (statusUser.contains("Online")) ? "1" : "0";
			}
			catch (Exception p_ex)
			{
				throw new TestException("Unable to read user status " + p_ex.toString());
			}

			// Getting login name
			try
			{
				user_name = elementProfile.findElement(elements().blockLoginName).getText();
			}
			catch (Exception p_ex)
			{
				throw new TestException("Unable to read user name " + p_ex.toString());

			}

			p_userList.put(position_in_list, new String[] { user_id, user_name, statusUser, numberOfAlerts });
			position_in_list++;
		}

		return p_userList;
	}

	/**
	 * Find message in message list, when message item find in parent web element
	 * @param p_messageKey
	 * @param element
	 * @return
	 */
	private boolean isMessagePresent(String p_messageKey, WebElement element)
	{
		int RowCount = element.findElements(elements().blockMessageOut).size();
		// Plus one element is required to find new message
		RowCount = RowCount + 2;

		for (int i = 1; i < RowCount; i++)
		{
			String locator = "./div[" + i + "]";
			String name = element.findElement(By.xpath(locator)).getText();
			if (name.contains(p_messageKey))
			{
				log().info("Message has been found " + name);
				return true;
			}
		}
		return false;
	}

	/**
	 * Find message in message list, when doesn't need child message item
	 * @param p_messageKey
	 * @param element
	 * @return
	 */
	private boolean findMessageSimple(String p_messageKey, WebElement element)
	{
		int RowCount = element.findElements(elements().blockMessageOut).size();

		for (int i = 0; i < RowCount; i++)
		{
			if (element.findElements(elements().blockMessageOut).get(i).getText().trim().contains(p_messageKey))
			{
				log().info("Message was found successfully!");
				return true;
			}
		}

		return false;
	}

	public boolean isMessagePresentInOldMessenger(String p_messageKey)
	{
		wd().waitForVisibility(elements().blockMessageText, "Block 'Message Text'");
		if (wd().isElementPresent(elements().blockMessageText))
		{
			List<WebElement> weLst = wd().getWebElements(elements().blockMessageText);
			for (WebElement l_we : weLst)
			{
				if (l_we.getText().equals(p_messageKey))
				{
					wd().flashWebElement(l_we);
					return true;
				}
			}
		}
		return false;
	}

	public boolean isMessengerOpenned()
	{
		// Check title of messenger
		return wd().isElementDisplayed(elements().txtTitle);
	}

	/**
	 * Check messages on equivalence
	 * @param p_messageKey String message key
	 * @return True or false
	 */
	public boolean isMessagePresent(String p_messageKey)
	{
		wd().waitForVisibility(elements().blockMessageText, "Block 'Message List'", true, 5);
		WebElement elMessages = wd().getWebElement(elements().blockMessageText);

		if (wd().isElementPresent(elements().blockMessageIn))
		{
			List<WebElement> l_incoming = elMessages.findElements(elements().blockMessageIn);
			log().info("Count of found incoming messages: " + l_incoming.size());

			for (int i = 0; i < l_incoming.size(); i++)
			{
				System.out.println(l_incoming.get(i).getText());

				if (l_incoming.get(i).getText().contains(p_messageKey))
				{
					log().info("Incoming message '" + p_messageKey + "' has been found successfully.");
					return true;
				}
			}
		}

		if (wd().isElementPresent(elements().blockMessageOut))
		{
			List<WebElement> l_outgoing = elMessages.findElements(elements().blockMessageOut);
			log().info("Count of found outgoing messages: " + l_outgoing.size());

			for (int i = 0; i < l_outgoing.size(); i++)
			{
				System.out.println(l_outgoing.get(i).getText());

				if (l_outgoing.get(i).getText().contains(p_messageKey))
				{
					log().info("Outgoing message '" + p_messageKey + "' has been found successfully.");
					return true;
				}
			}
		}

		log().info("Message '" + p_messageKey + "' hasn't been found.");
		return false;
	}

	public boolean isUpgradeBannerPresent()
	{
		return wd().isElementPresent(elements().btnUpgradeMessage);
	}

	public void typeMessage(String p_messageKey)
	{
		log().info("typeMessage: " + p_messageKey);
		wd().typeByIdJs(elements().blockInputMessage, p_messageKey);
	}

	public void submit()
	{
		log().info("Messenger press Submit");
		wd().waitForPresence(elements().btnSubmit, "Messenger submit button");
		wd().click(elements().btnSubmit);
	}

	// Waiters

	public void waitForInputField()
	{
		wd().waitForVisibility(elements().blockMessageInputField, "Block messenger input field");
	}

	public void clickUpgradeBanner()
	{
		// Click button upgrade message
		wd().waitForPresence(elements().btnUpgradeMessage, "Upgrade banner");
		wd().click(elements().btnUpgradeMessage);
	}

	public void clickCommunicationBanner()
	{
		wd().waitForPresence(elements().linkUpgradeFreeCommunication, "Communication banner");
		wd().click(elements().linkUpgradeFreeCommunication);
	}

	public void clickSpecialDeliveryBanner()
	{
		wd().waitForPresence(elements().linkUpgradeSpecialDelivery, "Special delivery banner");
		wd().click(elements().linkUpgradeSpecialDelivery);
	}

	public void clickMessengerInput()
	{
		wd().waitForPresence(elements().blockInputMessage, "Message input");
		wd().click(elements().blockInputMessage);
	}

	public void type(String p_value)
	{
		wd().waitForPresence(elements().blockInputMessage, "Message input");
		wd().typeAndClear(elements().blockInputMessage, p_value);
	}
}
